import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:kkhousekeep/page/home/convenient/visitor/record_detail.dart';
import 'package:kkhousekeep/tools/dialog_util.dart';
import 'package:kkhousekeep/tools/shared_preferences.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../../../models/home_room_entity.dart';
import '../../../../net/home_visitor_connect.dart';
import '../../../../net/respnse_code.dart';
import '../../../../widget/custom_picker_double.dart';

class CustomDateTime extends DateTime {
  CustomDateTime(super.year, super.month, super.day, super.hour, super.minute);

  @override
  String toString() {
    return "$month月$day日";
  }

  @override
  CustomDateTime add(Duration duration) {
    DateTime parent = super.add(duration);
    return CustomDateTime(
        parent.year, parent.month, parent.day, parent.hour, parent.minute);
  }
}

class VisitorPassPageController extends GetxController {
  List<DateTime> dayList = [];

  List<String> timeList = [];
  List<DateTime> leaveDayList = [];
  List<String> leaveTimeList = [];
  late DateTime now;
  late DateTime tomorrowDateTime;
  late DateTime arriveDateTime;
  late DateTime leaveDateTime;
  late DateTime latestLeftDateTime;
  late String today;
  late String tomorrow;
  var dayIndex = 0;
  var timeIndex = 0;
  var leaveDayIndex = 0;
  var leaveTimeIndex = 0;
  var visitorName = "";
  var visitorPhone = "";
  var arriveAddress = "".obs;
  var count = "";
  var startTime = "".obs;
  var endTime = "".obs;
  var licensePlate = "";
  var purpose = "";
  var isAsh = true.obs;

  late HomeVisitorConnect connect;

  @override
  void onInit() {
    super.onInit();
    connect = Get.find<HomeVisitorConnect>();
    _initAddress();
    _initList();
  }

  Future<void> submitVisitorInformation() async {
    DialogUtil.showNetworkLoading();
    var response = await connect.addRecord(
        visitor: visitorName,
        phoneNumber: visitorPhone,
        visitorNum: int.parse(count),
        visitStartTime: arriveDateTime.toString(),
        visitEndTime: leaveDateTime.toString(),
        licensePlate: licensePlate,
        visitReason: purpose);
    DialogUtil.dismiss();
    if (response == null) {
      return;
    }
    if (response.code == ResponseCode.success) {
      var sendCodeResponse = await connect.sendCodeToVisitor(response.obj.id);
      if (sendCodeResponse == null) {
        return;
      }
      if (sendCodeResponse.code == ResponseCode.success) {
        DialogUtil.showNetworkSucceed();
        Get.off(
          () => VisitorRecordDetail(
            visitorId: response.obj.id,
          ),
        );
        return;
      }
    }
    DialogUtil.showNetworkFail();
    return;
  }

  void _initAddress() async {
    var sp = await SharedPreferences.getInstance();
    HomeRoomObjList roomObjList = HomeRoomObjList.fromJson(
        jsonDecode(sp.getString(SpKey.roomInfo) ?? ''));
    arriveAddress.value = "${roomObjList.unitName}${roomObjList.roomName}";
  }

  void _initList() {
    now = DateTime.now();
    tomorrowDateTime = now.add(const Duration(days: 1));
    int currentHour = now.hour;
    int currentMinute = now.minute;
    today = "${now.month}月${now.day}日";
    tomorrow = "${tomorrowDateTime.month}月${tomorrowDateTime.day}日";
    DateTime tempDateTime;
    if (currentMinute < 30) {
      tempDateTime = DateTime(now.year, now.month, now.day, now.hour, 30);
    } else {
      tempDateTime = DateTime(now.year, now.month, now.day, now.hour + 1, 00);
    }

    for (int day = 0; day < 30; day++) {
      dayList.add(tempDateTime.add(Duration(days: day)));
    }

    //添加24小时的整点、半点
    for (int index = 0; index < 20; index++) {
      if ((index + 1) % 2 == 1) {
        timeList.add("0${index ~/ 2}:00");
      } else {
        timeList.add("0${index ~/ 2}:30");
      }
    }
    for (int index = 20; index < 48; index++) {
      if ((index + 1) % 2 == 1) {
        timeList.add("${index ~/ 2}:00");
      } else {
        timeList.add("${index ~/ 2}:30");
      }
    }

    //设置默认时刻
    if (currentMinute < 30) {
      timeIndex = currentHour * 2 + 1;
    } else if (currentMinute >= 30 && currentHour < 23) {
      timeIndex = currentHour * 2 + 2;
    } else {
      timeIndex = 0;
    }
  }

  void updateDateTime(int dayIndex, int timeIndex) {
    this.dayIndex = dayIndex;
    this.timeIndex = timeIndex;
  }

  ///时间选择器
  void buildTimePickWidget({required bool isArrive}) {
    FocusManager.instance.primaryFocus?.unfocus();
    Get.bottomSheet(
      CustomPickDouble<DateTime, String>(
          firstList: isArrive ? dayList : leaveDayList,
          secondList: isArrive ? timeList : leaveTimeList,
          firstIndex: isArrive ? dayIndex : leaveDayIndex,
          secondIndex: isArrive ? timeIndex : leaveTimeIndex,
          firstStringTransform: <DateTime>(dateTime) {
            return _dateTimeTransform(dateTime);
          },
          confirmCallBack: (firstIndex, secondIndex) {
            if (isArrive) {
              pickArriveTimeCallBack(firstIndex, secondIndex);
              return;
            }
            pickLeftTimeCallBack(firstIndex, secondIndex);
          }),
    );
  }

  void pickArriveTimeCallBack(int firstIndex, int secondIndex) {
    dayIndex = firstIndex;
    timeIndex = secondIndex;
    startTime.value =
        "${_dateTimeTransform<DateTime>(dayList[firstIndex])} ${timeList[secondIndex]}";

    DateTime selectDateTime = dayList[firstIndex];
    //构建到访时间
    arriveDateTime =
        DateTime(selectDateTime.year, selectDateTime.month, selectDateTime.day)
            .add(Duration(minutes: 30 * secondIndex));

    //构建最晚离开DateTime
    latestLeftDateTime = arriveDateTime.add(const Duration(hours: 2));
    //清空离开时间列表
    leaveDayList.clear();
    leaveTimeList.clear();
    leaveDayIndex = 0;
    leaveTimeIndex = 0;
    endTime.value = "";
    //往离开时间列表添加元素
    leaveDayList.add(dayList[firstIndex]);
    if (arriveDateTime.day != latestLeftDateTime.day) {
      leaveDayList.add(dayList[firstIndex + 1]);
    }
    //添加离开时刻元素
    for (int index = 0; index < 4; index++) {
      if (timeIndex + index + 1 < 48) {
        leaveTimeList.add(timeList[timeIndex + index + 1]);
      } else {
        leaveTimeList.add(timeList[timeIndex + index - 47]);
      }
    }
  }

  void pickLeftTimeCallBack(int firstIndex, int secondIndex) {
    leaveDateTime = _hourMinuteTransform(
        leaveTimeList[secondIndex], leaveDayList[firstIndex]);
    if (leaveDateTime.isAfter(latestLeftDateTime) ||
        leaveDateTime.isBefore(arriveDateTime)) {
      SmartDialog.showToast("时间间隔超过2小时");
      return;
    }
    leaveDayIndex = firstIndex;
    leaveTimeIndex = secondIndex;

    endTime.value =
        "${_dateTimeTransform(leaveDateTime)} ${leaveTimeList[secondIndex]}";
    _observeText();
  }

  String _dateTimeTransform<DateTime>(DateTime dateTime) {
    List<String> splitList = dateTime.toString().split(" ")[0].split("-");
    String month = splitList[1];
    if (month.contains("0")) {
      month = month.split("0")[1];
    }
    String day = splitList[2];
    String content = "$month月$day日";
    if (content == today) {
      return "今天";
    }
    if (content == tomorrow) {
      return "明天";
    }
    return content;
  }

  DateTime _hourMinuteTransform(String hourMinute, DateTime dateTime) {
    var hour = int.parse(hourMinute.split(":")[0]);
    var minute = int.parse(hourMinute.split(":")[1]);
    return DateTime(dateTime.year, dateTime.month, dateTime.day, hour, minute);
  }

  void updateName(String content) {
    visitorName = content;
    _observeText();
  }

  void updatePhone(String content) {
    visitorPhone = content;
    _observeText();
  }

  void updateCount(String content) {
    count = content;
    _observeText();
  }

  void updateLicensePlate(String content) {
    licensePlate = content;
    _observeText();
  }

  void updatePurpose(String content) {
    purpose = content;
    _observeText();
  }

  _observeText() {
    if (visitorName.isNotEmpty &&
        visitorPhone.isNotEmpty &&
        count.isNotEmpty &&
        startTime.isNotEmpty &&
        endTime.isNotEmpty) {
      isAsh.value = false;
      return;
    }
    isAsh.value = true;
  }
}
